上一篇我們提到了NN模型的三個分類 :: FC、CNN以及RNN
那我們到底要挑哪一個來當我們的模型呢?
答案是,沒有一定
什麼鬼答案? 這我也會!! 別急,我的意思是說,你可以都用看看,或是...
 
哇! 這也太多了吧? 到底怎麼挑啊? 很簡單,學習從模仿開始
上網爬了一下文,可以知道現今最強的RNN模型無非就是LSTM
它的特殊架構我就不提了。所以鑑於此,今天的實作會先從這個
最單純的RNN延伸模型 -- LSTM下手,讓我們敬請期待吧!
還記得幾篇之前提過ML三寶嗎? Dataset、Model和Computer ~
現在我們的Computer有了(GCP上的VM),Model決定了(LSTM),剩下的就是Dataset
而Kaggle正符合我們目前所需
Kaggle 是一個比賽的平台,內容通常以數據建模、分析為主,想當然上面有海量的資料集囉~
所以非常推薦每個人都去了解一下Kaggle的生態。這邊提供一個Kaggle API是為了方便下載數據用,對於較大的Dataset也是建議使用API下載,那麼話不多說,上SOP :
$sudo pip3 install kaggle
現在都喜歡搞金鑰嗎? 很麻煩耶! 為什麼要申請金鑰? 就只是因為你想下載kaggle的Dataset就必須登入而已
https://www.kaggle.com/<username>/account
<username>請填你的帳號(如 : https://www.kaggle.com/tom_hello87/account)Create API Token下載並把它放到~/.kaggle/裡面chmod 600 ~/.kaggle/kaggle.json
$kaggle
$kaggle datasets list -s stock
 
$kaggle datasets download ehallmar/daily-historical-stock-prices-1970-2018
$unzip daily-historical-stock-prices-1970-2018.zip
不,還早。
我知道我下的標題很不好,但確實很多人以為蒐集完三寶就可以開始把Dataset丟到Model裡面訓練。
但事情往往沒這麼容易。 的確,光是蒐集Dataset這點就是一個很大的難關,儘管你能夠拿到別人幫你蒐集的資料,但他所蒐集的資料格式、資料內容、甚至資料來源都不一定是你想要的。
How Google does Machine Learning的It's all about data和下面幾個Launching into Machine Learning的Generalization and Sampling的章節預處理有哪些步驟?
我們先來看一看daily-historical-stock-prices-1970-2018 dataset長什麼樣子吧!
現在知道了這個Dataset的長相之後,我們只要取我們關心的資料即可。
在此先嘗試我們所要的資料是adj_close價格,就是「adjusted closing price」的資訊即可。
這邊我所做的處理是將自己前30天的資料當作input,第30天的資料當作答案。
因為資料說實在超大,我希望切開來用TFRecord去存,以下程式碼片段所做的事情就是將資料讀進來、正規到0-1,最後分段存入TFRecord資料(然後也超~級~久~
# Create TFRecord
import os
import tensorflow as tf
def _bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=value))
def _int64_feature(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
def _float32_feature(value):
    return tf.train.Feature(float_list=tf.train.FloatList(value=value))
def create_tfrecords(days, stock_sc, save_name):
    stock_sc = np.asarray(stock_sc, np.float32)
    max_days = len(stock_sc)
    with tf.python_io.TFRecordWriter(save_name) as writer:
        for i in range(days, max_days):
            x = stock_sc[i-days:i, 0]
            y = stock_sc[i, 0]
            feature = {
                'x': _bytes_feature([x.tostring()]),
                'y': _float32_feature([y])}
            example = tf.train.Example(features=tf.train.Features(feature=feature))
            writer.write(example.SerializeToString())
            
# Data Normalization
from sklearn.preprocessing import MinMaxScaler
companies = names.ticker.unique()
scaler = MinMaxScaler()
days_before = 30
for company in companies:
    stock = prices.loc[prices['ticker'] == company]
    training_data = stock[['adj_close']].values
    # print(training_data.shape)
    try:
        ### scaler
        get_sc = scaler.fit_transform(training_data)
        # print(get_sc)
        create_tfrecords(days=days_before, stock_sc=get_sc, save_name='./generate_stock/'+company)
    except:
        print(company, training_data.shape)
我其實不確定自己訓練得對不對,明天再來看看怎麼樣驗證吧! 哈哈哈
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import os
reshape_size = 30
batch_size = 200
epochs = 20
def extract_features(example, reshape_size):
    features = tf.parse_single_example(
        example,
        features={
            'x': tf.FixedLenFeature([], tf.string),
            'y': tf.FixedLenFeature([], tf.float32),
        }
    )
    stock = tf.decode_raw(features['x'], tf.float32)
    stock = tf.reshape(stock, [reshape_size])
    stock = tf.cast(stock, tf.float32)
    stock = tf.expand_dims(stock, -1)
    label = features['y']
    return stock, label
tfrecords_path = './generate_stock/AEP'
dataset = tf.data.TFRecordDataset(tfrecords_path)
dataset = dataset.map(lambda x: extract_features(x, reshape_size))
dataset = dataset.shuffle(buffer_size=1000)
dataset = dataset.batch(batch_size, drop_remainder=True)
dataset = dataset.repeat()
train_gen = dataset.make_initializable_iterator()
# LSTM Training
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
model = Sequential()
model.add(LSTM(units = 50, return_sequences = True, input_shape = (reshape_size, 1)))
# model.add(LSTM(units = 92, return_sequences = True))
# model.add(Dropout(0.2))
# model.add(LSTM(units = 92, return_sequences = True))
# model.add(Dropout(0.2))
model.add(LSTM(units = 30, return_sequences = False))
model.add(Dense(units = 1))
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
with tf.Session() as sess:
    sess.run(train_gen.initializer)
    train = model.fit(train_gen, epochs = epochs, batch_size = batch_size, steps_per_epoch=100)
在Testing的時候,我有點後悔我將Data存成TFRecord,因為我對它其實並不熟悉,結果現在無法很順利地進行下去。
 
或許我試一試先不用TFRecord的方式來一遍好了Orz
今天先這樣~ 撤!
Stock Price Prediction Using Attention-based Multi-Input LSTM
你的股票資料依據是K線圖,K線圖是四個數值(當日收、開盤、最高、最低價)價組成,所以你需要抓每天四個數字來組成K線,單純抓K線只是個圖而已,你的那三個要素的其中兩個FC、CNN兩個抓取資料庫時,會不知道該抓哪個數值,到後面做RNN迴歸分析的時候,你的函數會無法建立的。
以上是我個人看了之後的一些看法,給您參考!
感謝您的回覆以及意見,我上方的網路結構沒有仔細說明,其實它並沒有使用到CNN和FC,只有單純的LSTM。
我上面只有取用每日的「調整後收盤價格」來做預測,只是單純想要看看它的效果。
之後如果要加入CNN,會在思考其他方式,,感謝您~!